"""
基于规则的前置安全检测验证器

在ML模型检测之前,先使用规则快速过滤明显的违规内容
"""
from typing import Callable, Dict, Optional, List, Set
from guardrails.validators import (
    Validator,
    ValidationResult,
    FailResult,
    PassResult,
    register_validator,
)
import re


@register_validator(name="rule-based-safety", data_type="string")
class RuleBasedSafety(Validator):
    """
    基于规则的前置安全检测验证器

    使用关键词黑名单、正则表达式和规则快速检测违规内容

    参数:
        banned_keywords: 禁用关键词列表
        banned_patterns: 禁用正则表达式模式列表
        max_length: 最大文本长度
        min_length: 最小文本长度
        case_sensitive: 是否区分大小写
        on_fail: 失败时的处理策略
    """

    def __init__(
        self,
        banned_keywords: Optional[List[str]] = None,
        banned_patterns: Optional[List[str]] = None,
        max_length: int = 5000,
        min_length: int = 1,
        case_sensitive: bool = False,
        on_fail: Optional[Callable] = None,
        **kwargs
    ):
        super().__init__(
            on_fail=on_fail,
            banned_keywords=banned_keywords,
            banned_patterns=banned_patterns,
            max_length=max_length,
            min_length=min_length,
            case_sensitive=case_sensitive,
            **kwargs
        )

        # 默认禁用关键词(常见违规词汇)
        default_banned_keywords = [
            # 政治敏感
            "暴力革命", "推翻政府", "颠覆国家",
            # 色情低俗
            "色情", "淫秽", "黄色",
            # 辱骂歧视
            "傻逼", "智障", "废物", "垃圾人",
            # 违法内容
            "制毒", "贩毒", "走私", "洗钱",
            # 个人信息泄露
            "身份证号", "银行卡密码",
        ]

        self.banned_keywords: Set[str] = set(
            banned_keywords if banned_keywords is not None else default_banned_keywords
        )

        # 默认禁用正则模式
        default_banned_patterns = [
            r'\d{15,18}',  # 身份证号格式
            r'\d{16,19}',  # 银行卡号格式
            r'1[3-9]\d{9}',  # 手机号格式
            r'\b(?:\d{1,3}\.){3}\d{1,3}\b',  # IP地址
        ]

        self.banned_patterns: List[re.Pattern] = [
            re.compile(pattern, re.IGNORECASE if not case_sensitive else 0)
            for pattern in (banned_patterns if banned_patterns is not None else default_banned_patterns)
        ]

        self.max_length = max_length
        self.min_length = min_length
        self.case_sensitive = case_sensitive

    def _validate(self, value: str, metadata: Dict) -> ValidationResult:
        """
        执行规则基础的验证

        参数:
            value: 待验证的文本
            metadata: 元数据

        返回:
            ValidationResult: 验证结果
        """
        if not isinstance(value, str):
            return FailResult(
                error_message="输入必须是字符串类型",
                fix_value=None
            )

        # 1. 检查空文本
        if not value.strip():
            return PassResult()

        # 2. 检查长度限制
        text_length = len(value)
        if text_length < self.min_length:
            return FailResult(
                error_message=f"文本长度({text_length})低于最小长度要求({self.min_length})",
                fix_value=None
            )

        if text_length > self.max_length:
            return FailResult(
                error_message=f"文本长度({text_length})超过最大长度限制({self.max_length})",
                fix_value=None
            )

        # 3. 检查禁用关键词
        search_text = value if self.case_sensitive else value.lower()
        keywords_to_check = self.banned_keywords if self.case_sensitive else {k.lower() for k in self.banned_keywords}

        found_keywords = []
        for keyword in keywords_to_check:
            if keyword in search_text:
                found_keywords.append(keyword)

        if found_keywords:
            return FailResult(
                error_message=f"文本包含禁用关键词: {', '.join(found_keywords[:3])}{'...' if len(found_keywords) > 3 else ''}",
                fix_value=None,
                metadata={
                    "rule_violation": "banned_keywords",
                    "found_keywords": found_keywords,
                    "is_safe": False
                }
            )

        # 4. 检查禁用正则模式
        found_patterns = []
        for pattern in self.banned_patterns:
            matches = pattern.findall(value)
            if matches:
                found_patterns.append({
                    "pattern": pattern.pattern,
                    "matches": matches[:3]  # 只记录前3个匹配
                })

        if found_patterns:
            return FailResult(
                error_message=f"文本匹配到禁用模式 (发现 {len(found_patterns)} 个违规模式)",
                fix_value=None,
                metadata={
                    "rule_violation": "banned_patterns",
                    "found_patterns": found_patterns,
                    "is_safe": False
                }
            )

        # 所有规则检查通过
        return PassResult(
            metadata={
                "rule_validation": "passed",
                "is_safe": True
            }
        )


@register_validator(name="simple-keyword-filter", data_type="string")
def simple_keyword_filter(value: str, metadata: Dict) -> ValidationResult:
    """
    简化的关键词过滤验证器 - 函数式实现

    参数:
        value: 待验证文本
        metadata: 元数据 (可包含 'keywords' 键)

    返回:
        ValidationResult
    """
    keywords = metadata.get('keywords', ["暴力", "色情", "赌博"])

    value_lower = value.lower()
    found = [kw for kw in keywords if kw.lower() in value_lower]

    if found:
        return FailResult(
            error_message=f"包含禁用关键词: {', '.join(found)}"
        )

    return PassResult()
